<?php
namespace Src\Middleware;

use Firebase\JWT\ExpiredException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Psr7\Factory\ResponseFactory;
use Src\utils\ResponseUtils;
use Exception;
use PDOException;
use Src\Utils\JWTUtils;
class AuthMiddleware
{

        private $responseFactory;
        public function __construct(ResponseFactory $responseFactory)
        {
                $this->responseFactory = $responseFactory;
        }
        public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): Response
        {
                $headers = $request->getHeaders();
                // 从session中获取用户信息
                error_log('phpsessid: ' . session_id());
                $current_user = $_SESSION['user'] ?? null;
                $autentication = $headers["Authorization"] ?? null;
                if (empty($autentication)) {
                        $autentication = $headers["authorization"] ?? null;
                }
                if (!isset($autentication[0]) || empty($current_user)) {
                        // 创建 $response 对象
                        $response = $this->responseFactory->createResponse();
                        $content = [
                                'code' => 401,
                                'success' => false,
                                'message' => 'no Permission or need login'
                        ];
                        $response = ResponseUtils::withJson($response, $content, 401);
                        return $response;
                }

                $token = str_replace('Bearer ', '', $autentication[0]);

                try {
                        $decoded = JWTUtils::decodeToken($token);
                        if (empty($decoded)) {
                                throw new Exception('Token has expired');
                        }
                        error_log('user: ' . json_encode($decoded->user));
                        $request = $request->withAttribute(name: 'user', value: $decoded->user);
                        return $handler->handle($request);
                } catch (ExpiredException $e) {
                        // 打印出 $e 的堆栈信息
                        error_log($e->getTraceAsString());
                        error_log($e->getMessage());
                        $content = [
                                'code' => 401,
                                'success' => false,
                                'message' => 'Token has expired'
                        ];
                        $response = $this->responseFactory->createResponse();
                        $response = ResponseUtils::withJson($response, $content, 401);
                        return $response;
                } catch (PDOException | Exception $e) {
                        throw $e;
                }
        }
}